package postgres

import (
	"context"
	"gorm.io/gorm"
	"manager/model"
	"manager/model/entity"
)

var Area = &area{}

type area struct{}

func (a *area) ExecTx(ctx context.Context, fn func(ctx context.Context) error) error {
	return db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		ctx = context.WithValue(ctx, contextTxKey{}, tx)
		return fn(ctx)
	})
}

func (a *area) Create(ctx context.Context, m *entity.Area) (int64, error) {
	err := dbWithContext(ctx).Create(m).Error
	return m.ID, err
}

func (a *area) Find(ctx context.Context, id int64) (*entity.Area, error) {
	e := &entity.Area{}
	err := dbWithContext(ctx).Model(&entity.Area{}).Find(&e, id).Error
	return e, err
}
func (a *area) FindByName(ctx context.Context, name string) (*entity.Area, error) {
	var (
		err error
		ety entity.Area
	)
	err = dbWithContext(ctx).Model(&entity.Area{}).Where("name = ?", name).Find(&ety).Error
	return &ety, err
}

func (a *area) Update(ctx context.Context, id int64, dict map[string]interface{}) error {
	return dbWithContext(ctx).Model(&entity.Area{}).Where("id = ?", id).Updates(dict).Error
}

func (a *area) Delete(ctx context.Context, id int64) error {
	return dbWithContext(ctx).Delete(&entity.Area{}, id).Error
}

func (a *area) List(ctx context.Context, in *model.AreaListRequest) (int, []*entity.Area, error) {
	var (
		q     = dbWithContext(ctx).Model(&entity.Area{})
		err   error
		total int64
		areas []*entity.Area
	)
	if in.Name != nil {
		q = q.Where("name like ?", "%"+*in.Name+"%")
	}

	if in.Id > 0 {
		q = q.Where("id = ?", in.Id)
	}

	if err = q.Count(&total).Error; err != nil {
		return 0, nil, err
	}
	if err = q.Order("created_at desc").Limit(in.Size).Offset((in.Index - 1) * in.Size).Find(&areas).Error; err != nil {
		return 0, nil, err
	}
	return int(total), areas, nil
}
